package com.share.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.share.utils.CryptoUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Slf4j
@Order(-2)
public class CustomLoginAbstractAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {

    private final AuthenticationManager authenticationManager;
    private final CryptoUtils cryptoUtils; // 改为final字段
    private final ObjectMapper objectMapper; // 添加ObjectMapper

    public CustomLoginAbstractAuthenticationProcessingFilter(
            AuthenticationManager authenticationManager,
            CryptoUtils cryptoUtils) { // 通过构造函数注入
        super(new AntPathRequestMatcher("/user/v1/login", "POST"));
        this.authenticationManager = authenticationManager;
        this.cryptoUtils = cryptoUtils;
        this.objectMapper = new ObjectMapper();
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        try {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            // 如果表单提交的数据为空，则尝试从请求体中解析 JSON 数据
            if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
                String requestBody = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);

                Map<String, String> credentials = objectMapper.readValue(requestBody, Map.class);
                username = credentials.get("username");
                password = credentials.get("password");

            }

            if (StringUtils.hasLength(password)) {
                try {
                    password = cryptoUtils.decrypt(password);
                } catch (Exception e) {
                    throw new AuthenticationException("密码解密失败") {};
                }
            }

            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(username, password);

            return authenticationManager.authenticate(authenticationToken);
        } catch (Exception e) {
            throw new AuthenticationException("认证失败: " + e.getMessage()) {};
        }
    }
}